/**
 * BPMProcess
 *
 * new BPMProcess({
 *
 * });
 * ------------------------------------
 *
 * API:
 *-------------------------------------
 * getBPMObjectType()
 * fromXML(processXml)
 * toXML()
 * addLink(link)
 * addNode(node)
 * getLinks()
 * getNode(nodeId)
 * getStartNode()
 * getMaxX()
 * setMaxX(maxX)
 * getMaxY()
 * setMaxY(maxY)
 */
(function(global){

    'use strict';

    const logger = WorkflowUtil.newLogger("WorkflowApp/BPMProcess");

    let BPMProcess = function () {

        BPMProcess.__super__.constructor.apply(this, arguments);

        //初始化属性
        this.addAttr("type", "", "t");
        this.addAttr("isShowShortName", "false", "s");

        this.addAttr("id", "", "i");
        this.addAttr("name", "", "n");
        this.addAttr("desc", "", "d");

        //暂时不知道这个属性是干什么的, usedNumberStr
        this.addAttr("uns", "", "u");

        //流程属性
        this.startNode = null;
        this.links = [];
        this.nodes = [];
        this.id2NodeMap = {};
        this.id2LineMap = {};

        //画图相关参数
        this.maxX = 0;
        this.maxY = 0;
    };
    //继承
    WorkflowUtil.extend(BPMProcess, global.BPMObject);

    BPMProcess.prototype.getBPMObjectType = function(){
        return WorkflowConstant.bpmObjType.BPMProcess;
    };

    /**
     * 从process中解析xml
     *
     * @param processXml
     */
    BPMProcess.prototype.fromXML = function(processXml){

       //重置流程
        this._reset();

        const xmlDoc = WorkflowUtil.getXMLDoc(processXml);

        const root = xmlDoc.documentElement.childNodes[0];

        //解析流程属性
        this.transXMLNode2BPMObject(root);

        //解析节点和线
        let child = root.firstChild;
        while (child != null){

            let type, nodeObje, link;

            type = child.getAttribute("t");

            if(type === WorkflowConstant.bpmObjType.BPMHumenActivity){

                nodeObje = new global.BPMHumenActivity();

            }else if(type === WorkflowConstant.bpmObjType.BPMTransition){

                link = new global.BPMTransition();
                nodeObje = link;

            }else if(type === WorkflowConstant.bpmObjType.BPMCircleLink){

            }else if(type === WorkflowConstant.bpmObjType.BPMStart){

                this.startNode = new global.BPMStart();
                nodeObje = this.startNode;

            }else if(type === WorkflowConstant.bpmObjType.BPMEnd){

                nodeObje = new global.BPMEnd();

            }else if(type === WorkflowConstant.bpmObjType.BPMAndRouter){

                nodeObje = new global.BPMAndRouter();
            }

            if(nodeObje != null){
                nodeObje.fromXML(child);

                if(type === WorkflowConstant.bpmObjType.BPMTransition){
                  this.addLink(nodeObje);
                }else if(type === WorkflowConstant.bpmObjType.BPMCircleLink){
                    // TODO 环形流程
                }else{
                  this.addNode(nodeObje);
                }
            }

            switch (type) {
            /*
            case WorkflowConstant.bpmObjType.BPMCircleLink:

                clink = new Clink("", "");
                clink.fromXML(child);
            //  Mutual.alert1("fromXML:"+BPMCircleLink+"|"+clink+"|"+child);
                var nodeId = child.attributes.k;
                var node:Node = Node(getChildById(nodeId,nodes));
                node.attachDownClink(clink);
                nodeId = child.attributes.j;
                node = Node(getChildById(nodeId,nodes));
                node.attachUpClink(clink);

                break;
            case WorkflowConstant.bpmObjType.BPMStart:
                break;
            case WorkflowConstant.bpmObjType.BPMEnd:
                break;
            case WorkflowConstant.bpmObjType.BPMAndRouter:
                break;*/
            default:
                break;
            }

            /*
            if (model != null) {
                model.fromXML(child);
                addChild(model);
            } else if(link != null){
                addChild(link);
            } else if(clink != null){
                addChild(clink);
            }

            if (type == Process.BPMHumenActivity){
                var childAttributes_0 = child.childNodes[0].attributes;
                var partyName = childAttributes_0.d;
                var partyType = childAttributes_0.g;
                var partyTypeId = childAttributes_0.f;
                var propName = child.childNodes[1].attributes.n;
                var isShowShortName = xml.attributes.s;
                var prefix:String = "";
                if(partyName != undefined && propName != undefined){
                    var nodeInfoStr:String = "";
                    var shortName = childAttributes_0.a;
                    //Mutual.alert("partyTypeId:="+partyTypeId);
                    if(shortName && shortName!="" && shortName!="null" && shortName!="undefined"){
                        nodeInfoStr += "(" + shortName + ")";
                    }
                    if(partyTypeId!="BlankNode"){//不是空节点
                        nodeInfoStr += partyName+"("+propName+")";
                    }else{
                        nodeInfoStr += partyName;
                    }
                    nodeInfoArr.push(nodeInfoStr);
                }
            }*/



            //==========================================

            child = child.nextSibling;
            while(child != null && child.nodeName === "cl"){
                child = child.nextSibling;
            }
        }


        //组装树
        const linkList = this.getLinks();
        for(let i = linkList.length - 1; i > -1; i--){

            const link = linkList[i];
            const fromId = link.getFromId();
            const toId = link.getToId();

            const fromNode = this.getNode(fromId);
            const toNode = this.getNode(toId);

            fromNode.addDonwLink(link);
            toNode.addUpLink(link);
            link.setPairNodes(fromNode, toNode);
        }
    };


    BPMProcess.prototype.toXML = function(psNode, docRoot){


        const pNode = docRoot.createElement("p");
        psNode.appendChild(pNode);

        // 节点
        for(let node of this.nodes){
            node.toXML(pNode, docRoot);
        }

        // 线
        for(let link of this.links){
            link.toXML(pNode, docRoot);
        }

        // FIXME 环行线

        // 解析属性
        this.parseAttr2Node(pNode);
    };

   /**
    * 添加线
    */
    BPMProcess.prototype.addLink = function(link){
      this.links.push(link);
      this.id2LineMap[link.getId()] = link;
    };


    /**
    * 增加节点
    */
    BPMProcess.prototype.addNode = function(node){
      this.nodes.push(node);
      this.id2NodeMap[node.getId()] = node;
    };

    /**
     * 获取所有的连接线
     */
    BPMProcess.prototype.getLinks = function(){
      return this.links;
    };

    /**
     * 获取节点
     */
    BPMProcess.prototype.getNodes = function(){
      return this.nodes;
    };

    /**
    * 获取节点
    */
    BPMProcess.prototype.getNode = function(nodeId){
      return this.id2NodeMap[nodeId];
    };

    /**
     *  获取开始节点
     */
    BPMProcess.prototype.getStartNode = function(){
      return this.startNode;
    };

    /**
     * 获取最大的 X 坐标
     */
    BPMProcess.prototype.getMaxX = function(){
      return this.maxX;
    };

    /**
     * 设置最大的 X
     */
    BPMProcess.prototype.setMaxX = function(maxX){
      this.maxX = maxX;
    };

    /**
     * 获取最大的 Y 坐标
     */
    BPMProcess.prototype.getMaxY = function(){
      return this.maxY;
    };

    /**
     * 设置最大的 Y
     */
    BPMProcess.prototype.setMaxY = function(maxY){
      this.maxY = maxY;
    };


    /**
     * 重置流程对象
     */
    BPMProcess.prototype._reset = function(){
        
        // 重置所有属性
        this.resetAllAtt();
    };

    
    
    
    global.BPMProcess = BPMProcess;

})(WorkflowApp);
